<script setup lang="ts">
import type { LocalProjectItem } from "@common/local-project.types.ts";
import { FolderOpenFilled, MoreOutlined } from "@ant-design/icons-vue";
import CustomIcon, { imgIcon } from "@/components/framework/icon";
import { hc } from "@/framework/vue/util/render.ts";
import { h, shallowRef } from "vue";
import type { ItemType } from "ant-design-vue";
import type { JetbrainsToolboxState } from "@/store/ide/types.ts";
import path from "@/framework/util/path.ts";
import { getFileIconBase64 } from "@/util/system-utils2.ts";

const { project } = defineProps<{
  project: LocalProjectItem;
}>();

const menuItems = shallowRef<ItemType[]>([]);

const openProject = (ideBin: string) => {
  // console.log(ideBin);
  native.cp.execFile(ideBin, [project.path], {});
};

const getIdeaMenuItem = (jbToolboxState: JetbrainsToolboxState) => {
  const idea = jbToolboxState.tools.find(it => it.toolId.startsWith("IDEA"));
  if (idea) {
    return {
      key: "idea",
      label: `使用 ${idea.displayName} 打开`,
      icon: imgIcon(path.join(idea.installLocation, "bin/idea.svg")),
      onClick: () => openProject(idea.launchCommand),
    };
  }
};

const getVsCodeMenuItem = async () => {
  let vscodeBin = "C:\\Program Files\\Microsoft VS Code\\Code.exe";
  if (!(await native.fs.exists(vscodeBin))) {
    vscodeBin = path.join(native.process.env.LOCALAPPDATA, "Programs\\Microsoft VS Code\\Code.exe");
  }
  if (await native.fs.exists(vscodeBin)) {
    const icon = await getFileIconBase64(vscodeBin);
    return {
      key: "vscode",
      label: `使用 VS Code 打开`,
      icon: imgIcon(icon),
      onClick: () => openProject(vscodeBin),
    };
  }
};

const getVisualStudioMenuItem = async () => {
  const baseDir = "C:\\Program Files\\Microsoft Visual Studio";
  const versions = await native.fs.readdir(baseDir);
  const vsBins: { name: string; bin: string; icon: string }[] = [];
  for (const versionDir of versions) {
    const editions = await native.fs.readdir(versionDir);
    for (const editionDir of editions) {
      const visualStudioBin = path.join(editionDir, "Common7\\IDE\\devenv.exe");
      if (await native.fs.exists(visualStudioBin)) {
        const version = path.basename(versionDir);
        const edition = path.basename(editionDir);

        const icon = await getFileIconBase64(visualStudioBin);
        vsBins.push({ name: `Visual Studio ${version} ${edition}`, bin: visualStudioBin, icon });
      }
    }
  }
  return vsBins;
};

const loadMenu = async () => {
  // 获取jetbrains toolbox已安装的IDE
  const jbToolboxState = await native.fs.readFileJson<JetbrainsToolboxState>("C:\\Users\\ZHANG\\AppData\\Local\\JetBrains\\Toolbox\\state.json");
  const menus: ItemType[] = [
    {
      key: "explorer",
      label: "在资源管理器中打开",
      icon: hc(FolderOpenFilled),
      onClick: () => native.shell.openPath(project.path),
    },
  ];
  if (jbToolboxState) {
    switch (project.type) {
      case "nodejs": {
        const webstorm = jbToolboxState.tools.find(it => it.toolId.startsWith("WebStorm"));
        if (webstorm) {
          menus.push({
            key: "webstorm",
            label: `使用 ${webstorm.displayName} 打开`,
            icon: imgIcon(path.join(webstorm.installLocation, "bin/webstorm.svg")),
            onClick: () => openProject(webstorm.launchCommand),
          });
        }
        const vscodeMenuItem = await getVsCodeMenuItem();
        if (vscodeMenuItem) menus.push(vscodeMenuItem);

        const ideaMenuItem = getIdeaMenuItem(jbToolboxState);
        if (ideaMenuItem) menus.push(ideaMenuItem);
        break;
      }
      case "java": {
        const ideaMenuItem = getIdeaMenuItem(jbToolboxState);
        if (ideaMenuItem) menus.push(ideaMenuItem);
        break;
      }
      case "python": {
        const pycharm = jbToolboxState.tools.find(it => it.toolId.startsWith("PyCharm"));
        if (pycharm) {
          menus.push({
            key: "pycharm",
            label: `使用 ${pycharm.displayName} 打开`,
            icon: imgIcon(path.join(pycharm.installLocation, "bin/pycharm.svg")),
            onClick: () => openProject(pycharm.launchCommand),
          });
        }
        const vscodeMenuItem = await getVsCodeMenuItem();
        if (vscodeMenuItem) menus.push(vscodeMenuItem);
        const ideaMenuItem = getIdeaMenuItem(jbToolboxState);
        if (ideaMenuItem) menus.push(ideaMenuItem);
        break;
      }
      case "dotnet": {
        const rider = jbToolboxState.tools.find(it => it.toolId.startsWith("Rider"));
        if (rider) {
          menus.push({
            key: "rider",
            label: `使用 ${rider.displayName} 打开`,
            icon: imgIcon(path.join(rider.installLocation, "bin/rider.svg")),
            onClick: () => openProject(rider.launchCommand),
          });
        }

        const vsBins = await getVisualStudioMenuItem();
        for (let vsBin of vsBins) {
          menus.push({
            key: `vs-${vsBin.name}`,
            label: `使用 ${vsBin.name} 打开`,
            icon: imgIcon(vsBin.icon),
            onClick: () => openProject(vsBin.bin),
          });
        }
        break;
      }
    }
  }

  menuItems.value = menus;
};
</script>

<template>
  <div class="project-item">
    <div class="project-item-icon">
      <custom-icon v-if="project.type === 'nodejs'" type="icon-nodejs" class="font-30" />
      <custom-icon v-if="project.type === 'java'" type="icon-java" class="font-30" />
      <custom-icon v-if="project.type === 'python'" type="icon-python" class="font-30" />
      <custom-icon v-if="project.type === 'dotnet'" type="icon-csharp" class="font-30" />
    </div>
    <div class="flex-column row-gap-5 overflow-auto">
      <div class="bold">{{ project.title }}</div>
      <div class="font-12 color-text-secondary text-ellipsis">{{ project.path }}</div>
    </div>
    <div class="text-center">
      <a-dropdown :trigger="['click']">
        <a-button :icon="hc(MoreOutlined)" type="text" shape="circle" @click="loadMenu" />

        <template #overlay v-if="menuItems.length > 0">
          <a-menu :items="menuItems" />
        </template>
      </a-dropdown>
    </div>
  </div>
</template>

<style scoped lang="less"></style>
